#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>




#define task_num 10

//预设一批任务
void sync_disk()
{
    printf("这是一个刷新数据的任务!\n");
}


void sync_log()
{
    printf("这是一个同步日志的任务!\n");
}


void net_send()
{
    printf("这是一个进行网络发送的任务!\n");
}



typedef void (*func) () ;  //重命名一个函数指针func

  func other_task[task_num] =  {NULL};//函数指针数组



int LoadTask(func fun_t)//将函数加载指针数组
{
   int i = 0;
   for( ; i<task_num; i++)
   {
     if(other_task[i] == NULL)
       break;

   }
   if(i == task_num) return -1; //指针数组已经满了，装载失败
   else other_task[i] = fun_t;

   return 0;
}


void InitTask()//初始化
{
  int i = 0;
  for(i=0; i<task_num; i++)
  {
    other_task[i]=NULL;

  }
    LoadTask(sync_disk);
    LoadTask(sync_log);
    LoadTask(net_send);
}

void RunTask()
{
  int i = 0;
  for(; i<task_num; i++)
  {
    if(other_task[i]==NULL)continue;
    other_task[i]();//对函数指针解引用，执行函数的内容
  }
}

int main()
{
  pid_t id = fork();
  if(id == 0)
  {
    //子进程
    int cnt = 50;
    while(cnt)
    {
        printf("我是子进程，我还活着呢，我还有%d 秒，pid：%d，ppid:%d\n",cnt--,getpid(),getppid());
        sleep(1);
    }
    exit(111);
  }

  InitTask();
  //父进程
  //pid_t ret_id = wait(NULL);  //阻塞等待
  
  while(1)
  {
    int status = 0;
    pid_t ret_id = waitpid(id,&status,WNOHANG);

    if(ret_id < 0)
        {
            printf("waitpid error!\n");
            exit(1);
        }
        else if(ret_id == 0)
        {
            RunTask();
            sleep(1);
            continue;
        }
        else{
            if(WIFEXITED(status)) // 是否收到信号
            {
                printf("wait success, child exit code: %d\n", WEXITSTATUS(status));
            }
            else
            {
                printf("wait success, child exit signal: %d\n", status & 0x7F);//异常退出，打印退出信号
            }
           // printf("我是父进程，等待子进程成功, pid: %d, ppid: %d, ret_id: %d, child exit code: %d, child exit signal: %d\n",\
           //     getpid(), getppid(), ret_id, (status>>8)&0xFF, status & 0x7F);
            break;
        }
  }
  return 0;
}
